"use client";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Progress } from "@/components/ui/progress";
import { Button } from "@/components/ui/button";
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { useEffect, useMemo, useState } from "react";
import { cn, formatPricePesos, getStatusColor } from "@/lib/utils";
import DialogCreateTask from "@/components/tasks/DialogCreateTask";
import { MdApartment } from "react-icons/md";
import AlertDeleteMaterial from "./AlertDeleteMaterial";
import AlertDeleteArea from "./AlertDeleteArea";
import TaskHeaderList from "@/components/tasks/TaskHeaderList";
import TaskRowList from "@/components/tasks/TaskRowList";
import { trpc } from "@/app/_trpc/client";
import { TbHomeEdit } from "react-icons/tb";
import DownloadPdfInvoice from "./DownloadPdfInvoice";
import CreateFloorSidebar from "./CreateFloorSidebar";
import AlertDeleteFloor from "./AlertDeleteFloor";
import { SelectedArea, SelectedMaterial } from "../types";
import { AreaSelect, FloorSelect } from "@/database/schema";
import {
EmplyPlaceHolder,
EmptyContent,
EmptyIcon,
EmptyTitle,
} from "@/components/EmplyPlaceHolder";
import ModifyCostsProjectSidebar from "./ModifyCostsProjectSidebar";
import { ModifyProjectStatusDialog } from "./ModifyProjectStatusDialog";
import { Badge } from "@/components/ui/badge";
import AreaFormSidebar from "./AreaFormSidebar";
import MaterialFormSidebar from "./MaterialFormSidebar";
type Tabs = "finances" | "materials" | "areas" | "tasks";
type TabList = {
value: Tabs;
label: string;
};
const TAB_LIST_PROJECT: TabList[] = [
{
label: "Finanzas",
value: "finances",
},
{
label: "Materiales",
value: "materials",
},
{
label: "Areas",
value: "areas",
},
{
label: "Tareas",
value: "tasks",
},
];
const SingleProjectPage = ({ id }: { id: string }) => {
const [selectedMaterial, setSelectedMaterial] =
useState<SelectedMaterial | null>(null);
const [selectedArea, setselectedArea] =
useState<SelectedArea | null>(null);
const [selectedFloor, setselectedFloor] =
useState<Partial<FloorSelect | null>>(null);
const [currenTab, setCurrentTab] = useState<Tabs>("areas");
const [project] = trpc.projects.getProjectById.useSuspenseQuery({value:id}, {
refetchOnMount: false,
refetchOnWindowFocus: false,
});
const compleatedAreas = useMemo(() => {
const allAreas = project?.floor
?.map((floor) => {
return floor?.areas;
})
.flat();
const areasCompleated = allAreas?.filter(
(area) => area.status === "revisada"
);
const compleatedPorcentage =
((areasCompleated?.length || 0) / (allAreas?.length || 0)) * 100;
return {
compleatedAreas: areasCompleated?.length,
totalAreas: allAreas?.length,
compleatedPorcentage,
};
}, [project]);
const handleParams = (e: React.MouseEvent<HTMLButtonElement>) => {
const target = e.currentTarget;
const { name } = target;
setCurrentTab(name as Tabs);
};
if (!project) {
return (
<div className="min-h-[80vh] grid place-content-center">
<EmplyPlaceHolder>
<EmptyTitle className="text-5xl font-bold">404</EmptyTitle>
<EmptyContent className="text-xl font-light">
Projecto no encontrado...
</EmptyContent>
</EmplyPlaceHolder>
</div>
);
}
return (
<div>
<header className="absolute -top-12 left-10 flex gap-12 border-b border-gray-300 pb-1">
<div className="flex items-end gap-2">
<div
className={cn(
" rounded-md grid place-content-center text-center p-2.5",
project?.residence === "casa" ? "bg-blue-100" : "bg-yellow-200"
)}
>
{project?.residence === "casa" ? (
<TbHomeEdit size={20} />
) : (
<MdApartment size={20} />
)}
</div>
<div className="relative">
<p className="text-xs font-light absolute -top-3 tracking-wide">
Projecto
</p>
<h2 className="text-xl font-semibold capitalize">
{project?.name}
</h2>
</div>
<Badge className={cn(getStatusColor(project.status),'ml-2 self-start')}>
{project.status}
</Badge>
</div>
</header>
<div className="">
<Tabs defaultValue={currenTab} className=" w-full ">
<TabsList className="bg-transparent w-full mb-10" asChild>
<div className="flex flex-wrap justify-center md:justify-between gap-x-10 mb-5 ">
<div>
{TAB_LIST_PROJECT.map((tab) => (
<TabsTrigger
key={tab.value}
value={tab.value}
name={tab.value}
className={cn(
"border-b-2 hover:border-primary/50 rounded-none shadow-none",
currenTab === tab.value && "border-b-primary"
)}
onClick={handleParams}
>
{tab.label}
</TabsTrigger>
))}
</div>
<div className="flex items-end gap-4 mt-2">
<ModifyProjectStatusDialog projectId={project.id}/>
<div className=" flex items-top justify-center">
<div className="mt-1">
<span className="font-light text-primary text-sm tracking-wider">
Progreso
</span>
<Progress
value={compleatedAreas?.compleatedPorcentage}
className="min-w-[200px]"
indicatorClassName={cn(
compleatedAreas?.compleatedPorcentage > 99
? "bg-green-600"
: "bg-primary"
)}
/>
</div>
<div className="">
<span>{compleatedAreas?.compleatedAreas}</span>
<span>/</span>
<span>{compleatedAreas?.totalAreas}</span>
</div>
</div>
</div>
</div>
</TabsList>
<TabsContent value="materials" className="w-full min-h-screen">
<div className="">
<div className="flex justify-between items-center">
<h2 className="text-xl md:text-2xl font-bold capitalize pt-5 mb-5">
materiales
</h2>
<div>
<MaterialFormSidebar project={project as any} />
</div>
</div>
<Table>
<TableHeader>
<TableRow>
<TableHead className="text-xs md:text-sm w-[100px]">
Nombre
</TableHead>
<TableHead className="text-xs md:text-sm">
Material requerido
</TableHead>
<TableHead className="text-xs md:text-sm">
Material utilizado
</TableHead>
<TableHead className="text-xs md:text-sm">
Material disponible
</TableHead>
<TableHead className="text-right text-xs md:text-sm ">
Opciones
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{project?.projectMaterials?.map(
({
materials,
availableQuantity,
requiredQuantity,
usedQuantity,
}) => (
<TableRow key={materials?.id}>
<TableCell className="font-medium text-nowrap text-xs md:text-sm">
{materials?.name}
</TableCell>
<TableCell>{requiredQuantity}</TableCell>
<TableCell
className={cn(
usedQuantity > requiredQuantity &&
"bg-red-200 text-xs md:text-sm"
)}
>
{usedQuantity}
</TableCell>
<TableCell className="text-xs md:text-base">
{availableQuantity}
</TableCell>
<TableCell className=" text-right text-xs md:text-sm">
<div className="flex justify-end items-start gap-1">
<button
onClick={() =>
setSelectedMaterial({
materialName: materials.name,
projectId: project?.id,
availableQuantity,
requiredQuantity,
usedQuantity,
projectName:project.name,
materialId:materials.id,
})
}
>
<MaterialFormSidebar
isEdit={true}
editValues={selectedMaterial!}
project={project as any}
/>
</button>
<button
onClick={() =>
setSelectedMaterial({
materialId: materials?.id,
materialName: materials?.name,
projectId: project?.id,
availableQuantity,
requiredQuantity,
projectName:project.name,
usedQuantity,
})
}
>
<AlertDeleteMaterial
selectedMaterial={selectedMaterial}
/>
</button>
</div>
</TableCell>
</TableRow>
)
)}
</TableBody>
</Table>
</div>
</TabsContent>
<TabsContent
value="areas"
className=" w-full min-h-screen pt-5 space-y-10"
>
<div className="flex justify-between items-center">
<div>
<h2 className="text-xl md:text-2xl font-bold">Areas</h2>
</div>
<div className="flex gap-3">
<div>
<CreateFloorSidebar projectId={project?.id!} projectName={project?.name!} />
</div>
<div>
<AreaFormSidebar project={project as any} />
</div>
</div>
</div>
{project?.floor?.map((floor) => (
<div key={floor?.id}>
<div className="flex gap-3">
<h2 className="text-base font-bold capitalize">
{floor?.name}
</h2>
<button onClick={() => setselectedFloor({ id: floor.id })}>
<AlertDeleteFloor selectedFloor={selectedFloor} />
</button>
</div>
<div>
<Table>
<TableHeader>
<TableRow>
<TableHead className="text-xs md:text-sm w-[100px]">
Tipo
</TableHead>
<TableHead className="text-xs md:text-sm">
Longitud
</TableHead>
<TableHead className="text-xs md:text-sm">
Ancho
</TableHead>
<TableHead className="text-xs md:text-sm">
Cantidad
</TableHead>
<TableHead className="text-xs md:text-sm">
Estado
</TableHead>
<TableHead className="text-right text-xs md:text-sm">
Opciones
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{floor?.areas?.map((area) => (
<TableRow key={area?.id}>
<TableCell className="font-medium text-nowrap text-xs md:text-sm">
{area?.type}
</TableCell>
<TableCell className="text-xs md:text-sm">
{area?.length}
</TableCell>
<TableCell className="text-xs md:text-sm">
{area?.width}
</TableCell>
<TableCell className="text-xs md:text-sm">
{area?.quantity}
</TableCell>
<TableCell className="text-xs md:text-sm">
{area?.status}
</TableCell>
<TableCell className=" text-right text-xs md:text-sm">
<div className="flex justify-end items-start gap-1">
<button
onClick={() =>
setselectedArea({
...area,
projectId: project.id,
projectName:project.name,
floorId:floor.id
})
}
>
<AreaFormSidebar isEdit={true} editValues={selectedArea!} project={project as any}/>
</button>
<button
onClick={() =>
setselectedArea({
...area,
projectId: project.id,
projectName:project.name,
floorId:floor.id
})
}
>
<AlertDeleteArea selectedArea={selectedArea} />
</button>
</div>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
))}
</TabsContent>
<TabsContent value="tasks" className=" w-full min-h-screen">
<div>
<div className="flex justify-between items-center">
<div>
<h3 className="text-xl md:text-2xl font-bold mb-5 pt-5">
Lista de tareas
</h3>
</div>
<div>
<DialogCreateTask currentSingleProject={project as any} />
</div>
</div>
{!project?.task || project?.task?.length <= 0 ? (
<div className="text-center pt-10 ">
<h4 className="text-base font-semibold">
Tareas aun no han sido asignadas
</h4>
</div>
) : (
<Table>
<TaskHeaderList />
<TableBody>
{project?.task?.map((task) => {
return <TaskRowList key={task?.id} task={task as any} />;
})}
</TableBody>
</Table>
)}
</div>{" "}
{/* <button className=" rounded-md border-gray-400 border-2 border-dashed w-full">
</button> */}
</TabsContent>
<TabsContent value="finances" className=" w-full min-h-screen ">
<section className="text-sm md:text-base flex flex-col md:flex-row gap-10 justify-between mt-10">
<div className="flex-1 ">
<div className="flex justify-between">
<h3 className=" text-xl font-semibold mb-3">Costos</h3>
<div>
<ModifyCostsProjectSidebar project={project as any} />
</div>
</div>
<form className="space-y-4">
<div>
<h4 className="font-semibold">Costo por metro</h4>
<p>{project?.costPerMeter}</p>
</div>
<div>
<p className="font-semibold">Costo total materiales</p>
<p>{formatPricePesos(project?.totalCostMaterials || 0)}</p>
</div>
<div>
<p className="font-semibold">Costo total mano de obra</p>
<p>{formatPricePesos(project?.laborCost || 0)}</p>
</div>
<div>
<p className="font-semibold">Costo total por metros</p>
<p>{formatPricePesos(project?.totalCostPerMeter || 0)}</p>
</div>
<div className="mt-5">
<p className="text-2xl font-bold mr-2">
{" "}
Total:
<span className="font-light">
{" "}
{formatPricePesos(
(project?.totalCostPerMeter || 0) +
(project?.laborCost || 0) +
(project?.totalCostMaterials || 0)
)}
</span>
</p>
</div>
</form>
</div>
<div className=" flex-1 rounded-xl">
<div className="flex justify-between">
<h3 className="text-xl font-semibold mb-3">Resumen</h3>
<DownloadPdfInvoice id={id} />
</div>
<div className="space-y-2">
<div>
<h4 className="font-semibold">Materiales</h4>
<div>
{project?.projectMaterials.length === 0 && (
<span className="text-xs">
Sin materiales definidos
</span>
)}
{project?.projectMaterials?.map((material) => {
return (
<article className="text-sm" key={material.id}>
<span>{material?.materials?.name}</span>
<span> x{material.requiredQuantity}</span>
</article>
);
})}
</div>
</div>
<div>
<h4 className="font-semibold">Areas</h4>
<div>
{project?.floor.length === 0 && (
<span className="text-xs">Sin areas definicas</span>
)}
{project?.floor?.map((area) => {
return (
<article className="text-sm" key={area.id}>
<span>{area?.name}</span>
<span> x{area?.areas?.length}</span>
</article>
);
})}
</div>
</div>
</div>
<div></div>
</div>
</section>
</TabsContent>
</Tabs>
</div>
</div>
);
};
export default SingleProjectPage;